home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / TCL1 / CTRACE2_ / CTRACE.C < prev    next >
Text File  |  1990-12-10  |  7KB  |  214 lines

  1. /*****     
  2.     CTRACE: A MESSAGE LOGGING CLASS
  3.     by William D. Cramer in Dr. Dobbs Journal #170, p. 44-55, 116-120.
  4. *****/
  5.  
  6. /** CTrace.c -- Methods for the trace document class. **/
  7. #include "CTrace.h"        /* trace class parameters */
  8.  
  9. /** Global declaration **/
  10. CTrace    *gTrace;        /* the one instance of this class */
  11.     
  12. /** ITrace() -- Initializes trace document object. **/
  13. void CTrace::ITrace
  14.     (    
  15.     short records        /* number of records before wrap */
  16.     )
  17. {
  18.     Rect    frameRect;        /* window frame */
  19.     CDocument::IDocument (gApplication, TRUE);
  20.     itsWindow = new (CWindow);
  21.     itsWindow->IWindow (TRACE_WINDOW_ID, FALSE, gDesktop, this);
  22.     itsWindow->GetFrame (&frameRect);
  23.     itsWindow->Move (gDesktop->bounds.right - frameRect.right - RIGHT_SMARGIN,gDesktop->bounds.top + TOP_SMARGIN);
  24.     itsLogPanorama = new (CLogPanorama);
  25.     itsLogPanorama->ILogPane (records, this, itsWindow);
  26.     itsMainPane = itsLogPanorama;
  27.     currMask = TRACE_DEFAULT_MASK;
  28.     gTrace = this;
  29. }
  30.  
  31. /** ToggleTraceWindow() -- Toggles visibility of trace window. **/
  32. void CTrace::ToggleTraceWindow(void)
  33. {
  34.     if (itsWindow->visible)
  35.         itsWindow->Hide ();
  36.     else
  37.     {
  38.         itsWindow->Show ();
  39.         itsWindow->Select ();
  40.     }
  41. }
  42.  
  43. /** Close() -- Overrides normal document method by closing trace window. **/
  44. Boolean CTrace::Close 
  45.     (
  46.     Boolean quitting                /* ignored */
  47.     )
  48. {
  49.     itsWindow->Hide ();
  50.     return (TRUE);
  51. }
  52.  
  53. /** SetTraceMask -- Allows user to set/clear defined trace masks.**/
  54. void CTrace::SetTraceMask (void)
  55. {
  56.     int     bitNum,         /* bit number within the trace mask */
  57.             checkBoxState,        /* state of a checkbox (0=unset,1=set) */
  58.             item,            /* loop counter */
  59.             itemType,        /* item type (4=button, 5=checkbox) */
  60.             whichItem;        /* item number selected by user */
  61.     Handle     itemStuff;        /* handle to dialog item parameters */
  62.     Boolean done;            /* loop-termination flag */
  63.     Str255     title;            /* text associated with a dialog item */
  64.     Rect    itemRect;        /* rectangle surrounding a control */
  65.     DialogPtr    maskDialog;        /* structure for dialog box */
  66.  
  67.     /* Pull up the mask dialog box out of the resource fork */
  68.     maskDialog = GetNewDialog (TRACE_MASK_DIALOG, NULL, (Ptr)(-1));
  69.     
  70.     /* Run through checkboxes */
  71.     for (item=FIRST_MASK, bitNum=0; 
  72.             item<=LAST_MASK; item++, 
  73.             bitNum++)
  74.     {
  75.         GetDItem (maskDialog, item, &itemType, &itemStuff, &itemRect);    
  76.         GetCTitle ( (ControlHandle)itemStuff, title);
  77.         PtoCstr ((char*)title);
  78.         if (strcmp((char*)title, "Undefined") != 0)
  79.         {
  80.             checkBoxState = ((currMask&(1L<<bitNum)) == 0L) ? 0 : 1;
  81.             SetCtlValue ( (ControlHandle) itemStuff, checkBoxState);
  82.         }
  83.         else
  84.             HiliteControl (itemStuff, UNHILITE_CONTROL);
  85.     }
  86.     /* The default button (#1) is the okay button, draw outline around it. */
  87.     GetDItem (maskDialog, OKAY_BUTTON_ITEM, &itemType, &itemStuff, &itemRect);
  88.     SetPort (maskDialog);
  89.     PenSize (3, 3);
  90.     InsetRect (&itemRect, -4, -4);
  91.     FrameRoundRect (&itemRect, 16, 16);    
  92.     
  93.     /* Get events from dialog manager and process accordingly */
  94.     done = FALSE;
  95.     while (!done)
  96.     {
  97.         ModalDialog (NULL, &whichItem);
  98.         GetDItem (maskDialog, whichItem, &itemType, &itemStuff, &itemRect);
  99.         switch (itemType)
  100.         {
  101.             case ctrlItem + btnCtrl :    /* CANCEL or OKAY */
  102.                 if (whichItem == OKAY_BUTTON_ITEM)
  103.         {
  104.             currMask = 0L;    
  105.              for (item=FIRST_MASK, bitNum=0; item<=LAST_MASK; item++, bitNum++)
  106.             {
  107.             GetDItem (maskDialog, item, &itemType, &itemStuff, &itemRect);
  108.                  checkBoxState = GetCtlValue ( (ControlHandle) itemStuff);
  109.                    currMask |= (checkBoxState==0) ? 0L : (1L<<bitNum);
  110.             }
  111.             done = TRUE;
  112.             }
  113.             else if (whichItem == CANCEL_BUTTON_ITEM)
  114.             done = TRUE;
  115.             break;
  116.         case ctrlItem + chkCtrl :    /* a category checkbox */
  117.             checkBoxState = GetCtlValue ( (ControlHandle) itemStuff);
  118.                 if (checkBoxState == 0)
  119.             SetCtlValue ( (ControlHandle) itemStuff, 1);
  120.                 else
  121.             SetCtlValue ( (ControlHandle) itemStuff, 0);
  122.                 break;
  123.             default:
  124.                 break;
  125.             }
  126.         }
  127.     
  128.     /* On exit, trash dialog record and controls */
  129.     DisposDialog (maskDialog);
  130. }
  131.  
  132. /** Trace() -- Checks current mask **/
  133. void CTrace::Trace
  134.     (
  135.     unsigned long mask,        /* severity of message */
  136.     char *format,            /* format for user's arguments */
  137.     ...                        /* arguments to format (varg) */
  138.     )
  139. {
  140. static char 
  141.     traceBuff[MAX_LOGREC_CHAR],    /* string that will be added to log */
  142.     userBuff[MAX_LOGREC_CHAR*2],    /* user's contribution to log record */
  143.     prefix[40];            /* date+time string */
  144. int
  145.     maxUserBuff;        /* maximum length of formatted user string */
  146. long    
  147.     timeSecs;        /* current time/date */
  148. DateTimeRec
  149.     dateRec;        /* time/date in MM/DD/YY HH:MM:SS components */
  150. /* Should the message get added to the trace log? */
  151. if ( (currMask & mask) != 0)
  152.     {
  153.     /* format the user's portion of the message */
  154.     vsprintf (userBuff, format, __va(format));
  155.     /* make sure the entire record will fit into traceBuff */
  156.     if (strlen (userBuff) > MAX_USER_BUFF)
  157.         userBuff[MAX_USER_BUFF] = NULL;
  158.     /* build log message and add it to the log */
  159.     GetDateTime (&timeSecs);
  160.     Secs2Date (timeSecs, &dateRec);
  161.     sprintf (traceBuff, "%02d/%02d/%02d--%02d:%02d:%02d %s", 
  162.             dateRec.month, dateRec.day, dateRec.year-1900, 
  163.             dateRec.hour, dateRec.minute, dateRec.second,
  164.             userBuff);
  165.     itsLogPanorama->AddString (traceBuff);
  166.     }
  167. }
  168.  
  169. /** IsItVisible() -- Returns 'visible' flag to update menu bar entries. **/
  170. Boolean CTrace::IsItVisible(void)
  171. {
  172.     return (itsWindow->visible);
  173. }
  174.  
  175. /** UpdateMenus() -- Disables Save and Revert entries **/
  176. void CTrace::UpdateMenus(void)
  177. {
  178.     inherited::UpdateMenus ();;
  179.     gBartender->DisableCmd (cmdSave);
  180.     gBartender->DisableCmd (cmdRevert);
  181. }
  182.  
  183. /** DoSaveAs() -- Writes out contents of itsLogList to indicated file. **/
  184. Boolean CTrace::DoSaveAs 
  185.     (
  186.     SFReply *macSFReply        /* the user's choice of file */
  187.     )
  188. {
  189.     char    logRecBuff[MAX_LOGREC_CHAR];    /* buffer for log entry */
  190.     short    maxRec,             /* number of records in LogList */
  191.             offsetToNull,        /* byte offset to end of log entry */
  192.             rec;                /* loop counter */
  193.     /* Dispose of the data used for the old file record */
  194.     if (itsFile != NULL)
  195.         itsFile->Dispose ();
  196.     /* Set up the new data file (no error checking!) */
  197.     itsFile = new (CDataFile);
  198.     ((CDataFile *)itsFile)->IDataFile ();
  199.     itsFile->SFSpecify (macSFReply);
  200.     itsFile->CreateNew (gSignature, 'TEXT');
  201.     itsFile->Open (fsRdWrPerm);
  202.     
  203.     /*  Write out all records in list (add carriage return to end of each line).*/
  204.     maxRec = (short)(itsLogPanorama->itsLogList)->GetNumItems();
  205.     for (rec=1; rec<=maxRec; rec++) 
  206.     {
  207.         (itsLogPanorama->itsLogList)->GetString (rec, logRecBuff);
  208.         offsetToNull = strlen (logRecBuff);
  209.         logRecBuff[offsetToNull] = '\r';
  210.         ((CDataFile*)itsFile)->WriteSome (logRecBuff, offsetToNull+1);
  211.     }        
  212.     return (TRUE);
  213. }
  214.